package model.elements;

import model.collisions.CollisionCategory;
import model.elements.attributes.Coordinate2D;
import model.elements.attributes.Damage;
import model.elements.attributes.Speed;
import model.elements.behaviours.DoesDamage;
import model.elements.behaviours.Mobile;
import model.elements.commands.ElementCommandFactory;
import model.elements.states.movement.ElementMovementState;
import model.elements.states.movement.MovingRight;
import model.elements.states.movement.Stopped;
import model.exceptions.CommandFactoryIsNotReady;
import model.exceptions.ModelExceptions;
import model.movement.MovementEngine;

// TODO: Auto-generated Javadoc
/**
 * The Class Explotion.
 */
public class Explotion extends TemporalSingleCommandElement implements DoesDamage, Mobile {

	/** The m_speed. */
	private Speed 					m_speed;
	
	/** The m_damage. */
	private Damage 					m_damage;
	
	/** The m_movement sate. */
	private ElementMovementState 	m_movementSate;
	
	/** The m_facing to. */
	private ElementMovementState 	m_facingTo;
	
	/**
	 * Inits the.
	 *
	 * @param type the type
	 * @param blastDamage the blast damage
	 * @param blastRange the blast range
	 */
	private void init(CollisionCategory type, Damage blastDamage, int blastRange) {
		m_lifeState.setCategory(type);
		m_speed 		= new Speed(1);
		m_damage 		= blastDamage;
		m_movementSate	= new Stopped();
		m_facingTo		= new MovingRight();
		m_ttl.setValue( blastRange );
	}
	
	/**
	 * Instantiates a new explotion.
	 *
	 * @param position the position
	 * @param direction the direction
	 * @throws ModelExceptions the model exceptions
	 */
	public Explotion( Coordinate2D position, ElementMovementState direction ) throws ModelExceptions {
		super( position, ElementCommandFactory.getElementMove( direction ) );
		init( CollisionCategory.C_L1_EXPLOTION, new Damage(999), 5 );
	}
	
	/**
	 * Instantiates a new explotion.
	 *
	 * @param position the position
	 * @param direction the direction
	 * @param type the type
	 * @throws ModelExceptions the model exceptions
	 */
	public Explotion( Coordinate2D position, ElementMovementState direction, CollisionCategory type ) throws ModelExceptions {
		super( position, ElementCommandFactory.getElementMove( direction ) );
		init( type, new Damage(999), 5 );
	}
	
	/**
	 * Instantiates a new explotion.
	 *
	 * @param position the position
	 * @param direction the direction
	 * @param type the type
	 * @param blastDamage the blast damage
	 * @param blastRange the blast range
	 * @throws ModelExceptions the model exceptions
	 */
	public Explotion( Coordinate2D position, ElementMovementState direction, CollisionCategory type, Damage blastDamage, int blastRange ) throws ModelExceptions {
		super( position, ElementCommandFactory.getElementMove( direction ) );
		init( type, blastDamage, blastRange );
	}

	/**
	 * Sets the speed.
	 *
	 * @param speed the new speed
	 */
	protected void setSpeed(double speed) { m_speed.setBaseSpeed(speed); }	

	/* (non-Javadoc)
	 * @see model.elements.TemporalSingleCommandElement#setTTL(int)
	 */
	@Override
	protected void setTTL(int ttl) { m_ttl.setValue(ttl); }

	/* (non-Javadoc)
	 * @see model.elements.behaviours.Mobile#setPosition(model.elements.attributes.Coordinate2D)
	 */
	@Override
	public void setPosition(Coordinate2D position) {
		m_currentPosition = position;
	}

	/* (non-Javadoc)
	 * @see model.elements.behaviours.Mobile#getSpeed()
	 */
	@Override
	public Speed getSpeed() {
		return m_speed;
	}

	/* (non-Javadoc)
	 * @see model.elements.behaviours.Mobile#getNextPosition()
	 */
	@Override
	public Coordinate2D getNextPosition() {
		return MovementEngine.getNextPositionForNonAcceleratedMovement(
				m_currentPosition, 
				m_movementSate, 
				m_speed
		);}
	
	/* (non-Javadoc)
	 * @see model.elements.behaviours.Mobile#getNextTile()
	 */
	@Override
	public Coordinate2D getNextTile()
	{
		return MovementEngine.getNextPositionForNonAcceleratedMovement(
				m_currentPosition, 
				m_movementSate, 
				new Speed(1.0) 
		);
	}

	/* (non-Javadoc)
	 * @see model.elements.behaviours.Mobile#setMovementState(model.elements.states.movement.ElementMovementState)
	 */
	@Override
	public void setMovementState(ElementMovementState movementState) {
		m_facingTo = movementState.getFacingTo(m_movementSate);
		m_movementSate = movementState;
	}

	/* (non-Javadoc)
	 * @see model.elements.behaviours.DoesDamage#doDamage()
	 */
	@Override
	public Damage doDamage() {
		return m_damage;
	}

	/* (non-Javadoc)
	 * @see model.elements.behaviours.Mobile#getDirection()
	 */
	@Override
	public ElementMovementState getDirection() {
		return m_facingTo;
	}

    /**
     * Stop and die.
     *
     * @throws CommandFactoryIsNotReady the command factory is not ready
     */
    public void stopAndDie() throws CommandFactoryIsNotReady
    {
        m_lifeState.setCommand(ElementCommandFactory.getElementDoesNothing());        
    }

}
